<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>chillGarden · RAG 上传</title>
  <script src="https://cdn.tailwindcss.com"></script>
  <style>
    /* chillGarden 轻松自然风格 */
    .cg-gradient { background: linear-gradient(135deg, #e0f7f4 0%, #f3f8ff 100%); }
    .cg-card { backdrop-filter: blur(6px); }
    .cg-accent { color: #0ea5a5; }
    .cg-btn { background: linear-gradient(135deg, #0ea5a5, #22c55e); }
    .cg-btn:hover { filter: brightness(1.05); }
  </style>
</head>
<body class="cg-gradient min-h-screen">
  <header class="max-w-4xl mx-auto px-6 pt-8 flex items-center justify-between">
    <div class="flex items-center gap-2">
      <span class="text-2xl font-semibold cg-accent">chillGarden</span>
      <span class="text-sm text-gray-500">轻松管理你的知识花园</span>
    </div>
    <div class="text-xs text-gray-500">RAG Uploader</div>
  </header>

  <main class="max-w-4xl mx-auto px-6 py-6">
    <section class="bg-white/70 cg-card rounded-2xl shadow-sm border border-gray-200">
      <div class="px-6 py-5 border-b border-gray-100 flex items-center justify-between">
        <h1 class="text-xl font-semibold text-gray-800">知识库上传</h1>
        <span class="text-xs text-gray-500">保持轻盈、简洁的 chillGarden 设计</span>
      </div>

      <div class="p-6 space-y-6">
        <!-- 标签选择与新增 -->
        <div class="space-y-2">
          <label class="block text-sm font-medium text-gray-700">标签</label>
          <div class="flex items-center gap-3">
            <select id="tagSelect" class="flex-1 border-gray-300 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-teal-400"></select>
            <input id="newTagInput" class="w-48 border-gray-300 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-teal-400" placeholder="输入新标签" />
            <button id="addTagBtn" class="px-4 py-2 text-white rounded-lg text-sm cg-btn">新增</button>
          </div>
          <p class="text-xs text-gray-500">选择或新增一个标签，文件将带有该标签存入向量库。</p>
        </div>

        <!-- 文件选择 -->
        <div class="space-y-2">
          <label class="block text-sm font-medium text-gray-700">文件</label>
          <input id="fileInput" type="file" multiple class="mt-1 w-full text-sm file:mr-3 file:px-3 file:py-2 file:rounded-lg file:border-0 file:text-sm file:bg-teal-50 file:text-teal-700 hover:file:bg-teal-100" />
          <div id="fileList" class="mt-2 text-xs text-gray-600"></div>
        </div>

        <!-- 上传与进度 -->
        <div class="flex items-center gap-4">
          <button id="uploadBtn" class="px-5 py-2.5 text-white rounded-lg cg-btn">开始上传</button>
          <div id="status" class="text-sm text-gray-600"></div>
        </div>

        <div class="hidden" id="progressWrap">
          <div class="w-full bg-gray-200 rounded h-2">
            <div id="progressBar" class="bg-teal-500 h-2 rounded" style="width:0%"></div>
          </div>
          <div id="progressText" class="text-xs text-gray-500 mt-1">0%</div>
        </div>
      </div>
    </section>
  </main>

  <footer class="max-w-4xl mx-auto px-6 pb-8 text-xs text-gray-400">© chillGarden</footer>

  <script>
    const BASE = 'http://localhost:8090/api/v1/rag';

    async function loadTags() {
      try {
        const res = await fetch(`${BASE}/query_rag_tag_list`);
        const data = await res.json();
        const list = data?.data || [];
        const sel = document.getElementById('tagSelect');
        sel.innerHTML = '';
        list.forEach(t => {
          const opt = document.createElement('option');
          opt.value = t;
          opt.textContent = t;
          sel.appendChild(opt);
        })
      } catch (e) {
        console.warn('加载标签失败', e);
      }
    }

    async function addTag() {
      const input = document.getElementById('newTagInput');
      const val = (input.value || '').trim();
      if (!val) return;
      const fd = new FormData();
      fd.append('ragTag', val);
      try {
        const res = await fetch(`${BASE}/tag/add`, { method: 'POST', body: fd });
        const data = await res.json();
        if (data?.code === '0000') {
          input.value = '';
          await loadTags();
          document.getElementById('tagSelect').value = val;
          toast('标签新增成功');
        } else {
          toast(data?.info || '标签新增失败');
        }
      } catch (e) {
        toast('网络错误或服务不可用');
      }
    }

    function humanSize(bytes) {
      const units = ['B','KB','MB','GB'];
      let i = 0; let b = bytes;
      while (b > 1024 && i < units.length-1) { b/=1024; i++; }
      return `${b.toFixed(1)} ${units[i]}`;
    }

    function renderFileList(files) {
      const wrap = document.getElementById('fileList');
      if (!files.length) { wrap.textContent = '未选择文件'; return; }
      wrap.innerHTML = Array.from(files).map(f => `• ${f.name}（${humanSize(f.size)}）`).join('<br/>');
    }

    function setProgress(percent) {
      const bar = document.getElementById('progressBar');
      const text = document.getElementById('progressText');
      const wrap = document.getElementById('progressWrap');
      wrap.classList.remove('hidden');
      bar.style.width = `${percent}%`;
      text.textContent = `${percent}%`;
    }

    async function upload() {
      const tag = document.getElementById('tagSelect').value;
      const files = document.getElementById('fileInput').files;
      if (!tag) { toast('请先选择或新增标签'); return; }
      if (!files.length) { toast('请至少选择一个文件'); return; }

      const statusEl = document.getElementById('status');
      statusEl.textContent = '上传中...';
      setProgress(5);

      const fd = new FormData();
      fd.append('ragTag', tag);
      Array.from(files).forEach(f => fd.append('file', f));

      try {
        const res = await fetch(`${BASE}/file/upload`, { method: 'POST', body: fd });
        const data = await res.json();
        if (data?.code === '0000') {
          setProgress(100);
          statusEl.textContent = '';
          toast('上传成功');
        } else {
          statusEl.textContent = '';
          toast(data?.info || '上传失败');
        }
      } catch (e) {
        statusEl.textContent = '';
        toast('网络错误或服务不可用');
      }
    }

    // 简易 toast 提示
    function toast(msg) {
      const el = document.createElement('div');
      el.className = 'fixed bottom-6 left-1/2 -translate-x-1/2 bg-gray-900 text-white text-sm px-4 py-2 rounded-lg shadow';
      el.textContent = msg;
      document.body.appendChild(el);
      setTimeout(() => { el.remove(); }, 1800);
    }

    document.getElementById('fileInput').addEventListener('change', (e) => renderFileList(e.target.files));
    document.getElementById('uploadBtn').addEventListener('click', upload);
    document.getElementById('addTagBtn').addEventListener('click', addTag);
    document.getElementById('newTagInput').addEventListener('keydown', (e) => { if (e.key === 'Enter') addTag(); });

    loadTags();
  </script>
</body>
</html>
